/*
 * @(#)Eclipse3xJideTabbedPaneUI.java 8/28/2006
 *
 * Copyright 2002 - 2006 JIDE Software Inc. All rights reserved.
 */

package com.element.plaf.eclipse;

import com.element.plaf.UIDefaultsLookup;
import com.element.plaf.vsnet.VsnetJideTabbedPaneUI;
import com.element.ui.tabs.JideTabbedPane;
import com.element.ui.tabs.JideTabbedPane.NoFocusButton;
import com.element.util.UIUtil;

import javax.swing.*;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicGraphicsUtils;
import javax.swing.text.View;
import java.awt.*;

/**
 * A eclipse L&f implementation of JideTabbedPaneUI
 */
public class Eclipse3xJideTabbedPaneUI extends VsnetJideTabbedPaneUI {
	// pixels
	protected int _closeButtonMargin;// margin around the close button

	protected int _closeButtonMarginSize;// margin of the close button when every tab has a close button

	protected int _iconMarginHorizon;// distance from icon to tab rect start when the tab is on the top or bottom

	protected int _iconMarginVertical;// distance from icon to tab rect start when the tab is on the left or right

	@SuppressWarnings({"UnusedDeclaration"})
	public static ComponentUI createUI(JComponent c) {
		return new Eclipse3xJideTabbedPaneUI();
	}

	@Override
	public void installUI(JComponent c) {
		super.installUI(c);
		_rectSizeExtend = 12;
	}

	@Override
	protected void installDefaults() {
		super.installDefaults();
		// set the border of the TabbedPane
		LookAndFeel.installBorder(_tabPane, "JideTabbedPane.border");
		_closeButtonMargin = UIDefaultsLookup.getInt("JideTabbedPane.closeButtonMargin");
		_closeButtonMarginSize = UIDefaultsLookup.getInt("JideTabbedPane.closeButtonMarginSize");
		_iconMarginHorizon = UIDefaultsLookup.getInt("JideTabbedPane.iconMarginHorizon");
		_iconMarginVertical = UIDefaultsLookup.getInt("JideTabbedPane.iconMarginVertical");
	}

	@Override
	public void paintBackground(Graphics g, Component c) {
		if (getTabShape() == JideTabbedPane.SHAPE_ECLIPSE3X) {
			if (_tabPane.isOpaque()) {
				int width = c.getWidth();
				int height = c.getHeight();

				int temp1 = -1;
				int temp2 = -1;
				if (isTabLeadingComponentVisible()) {
					if (height < _tabLeadingComponent.getSize().height) {
						height = _tabLeadingComponent.getSize().height;
						temp1 = _tabLeadingComponent.getSize().height;
					}
					if (width < _tabLeadingComponent.getSize().width) {
						width = _tabLeadingComponent.getSize().width;
						temp2 = _tabLeadingComponent.getSize().width;
					}
				}

				if (isTabTrailingComponentVisible()) {
					if (height < _tabTrailingComponent.getSize().height && temp1 < _tabTrailingComponent.getSize().height) {
						height = _tabTrailingComponent.getSize().height;
					}
					if (width < _tabTrailingComponent.getSize().width && temp2 < _tabTrailingComponent.getSize().width) {
						width = _tabTrailingComponent.getSize().width;
					}
				}

				g.setColor(_background);
				g.fillRect(0, 0, width, height);
			}
		} else {
			super.paintBackground(g, c);
		}
	}

	@Override
	protected void ensureCurrentLayout() {
		/*
		 * If tabPane doesn't have a peer yet, the validate() call will silently
		 * fail. We handle that by forcing a layout if tabPane is still invalid.
		 * See bug 4237677.
		 */
		if (!_tabPane.isValid()) {
			TabbedPaneLayout layout = (TabbedPaneLayout) _tabPane.getLayout();
			layout.calculateLayoutInfo();
		}

		// ensure the bounds of the close buttons when they are showed on the
		// tab
		if (scrollableTabLayoutEnabled() && isShowCloseButton()
				&& isShowCloseButtonOnTab()) {
			for (int i = 0; i < _closeButtons.length; i++) {
				if (_tabPane.isShowCloseButtonOnSelectedTab()) {
					if (i != _tabPane.getSelectedIndex()) {
						_closeButtons[i].setBounds(0, 0, 0, 0);
						continue;
					}
				} else {
					if (i >= _rects.length) {
						_closeButtons[i].setBounds(0, 0, 0, 0);
						continue;
					}
				}

				if (!_tabPane.isTabClosableAt(i)) {
					_closeButtons[i].setBounds(0, 0, 0, 0);
					continue;
				}
				Dimension size = _closeButtons[i].getPreferredSize();

				Rectangle bounds;
				if (_closeButtonAlignment == SwingConstants.TRAILING) {
					if (_tabPane.getTabPlacement() == JideTabbedPane.TOP || _tabPane.getTabPlacement() == JideTabbedPane.BOTTOM) {
						if (_tabPane.getComponentOrientation().isLeftToRight()) {
							bounds = new Rectangle(_rects[i].x + _rects[i].width - size.width - 16, _rects[i].y + ((_rects[i].height - size.height) >> 1), size.width, size.height);
						} else {
							bounds = new Rectangle(_rects[i].x + 4, ((_rects[i].height - size.height) >> 1), size.width, size.height);
						}
					} else if (_tabPane.getTabPlacement() == JideTabbedPane.LEFT) {
						bounds = new Rectangle(_rects[i].x + ((_rects[i].width - size.width) >> 1), _rects[i].y + _rects[i].height - size.height - 16, size.width, size.height);
					} else /*if (_tabPane.getTabPlacement() == JideTabbedPane.RIGHT)*/ {
						bounds = new Rectangle(_rects[i].x + ((_rects[i].width - size.width) >> 1), _rects[i].y + _rects[i].height - size.height - 16, size.width, size.height);
					}
				} else {
					bounds = new Rectangle(_rects[i].x + 4, ((_rects[i].height - size.height) >> 1), size.width, size.height);
					if (!_tabPane.getComponentOrientation().isLeftToRight() && (_tabPane.getTabPlacement() == JideTabbedPane.TOP || _tabPane.getTabPlacement() == JideTabbedPane.BOTTOM)) {
						bounds = new Rectangle(_rects[i].x + _rects[i].width - size.width - 16, _rects[i].y + ((_rects[i].height - size.height) >> 1), size.width, size.height);
					}
				}
				if (_closeButtons[i] instanceof NoFocusButton) {
					((NoFocusButton) _closeButtons[i]).setIndex(i);
				}
				if (!bounds.equals(_closeButtons[i].getBounds())) {
					_closeButtons[i].setBounds(bounds);
				}
				if (_tabPane.getSelectedIndex() == i) {
					_closeButtons[i].setBackground(_selectedColor == null ? _tabPane.getBackgroundAt(i) : _selectedColor);
				} else {
					_closeButtons[i].setBackground(_tabPane.getBackgroundAt(i));
				}
			}
		}

	}

	/**
	 * Paints the tabs in the tab area. Invoked by paint(). The graphics parameter must be a valid <code>Graphics</code>
	 * object. Tab placement may be either: <code>JTabbedPane.TOP</code>, <code>JTabbedPane.BOTTOM</code>,
	 * <code>JTabbedPane.LEFT</code>, or <code>JTabbedPane.RIGHT</code>. The selected index must be a valid tabbed pane
	 * tab index (0 to tab count - 1, inclusive) or -1 if no tab is currently selected. The handling of invalid
	 * parameters is unspecified.
	 *
	 * @param g             the graphics object to use for rendering
	 * @param tabPlacement  the placement for the tabs within the JTabbedPane
	 * @param selectedIndex the tab index of the selected component
	 */
	@Override
	protected void paintTabArea(Graphics g, int tabPlacement, int selectedIndex, Component c) {

		if (!PAINT_TABAREA) {
			return;
		}

		if (getTabShape() == JideTabbedPane.SHAPE_ECLIPSE3X) {
			int tabCount = _tabPane.getTabCount();

			Rectangle iconRect = new Rectangle(), textRect = new Rectangle();
			Rectangle clipRect = g.getClipBounds();
			Rectangle viewRect = _tabScroller.viewport.getViewRect();

			if (_tabPane.isOpaque()) {
				g.setColor(_tabBackground);
				g.fillRect(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
			}

			// Paint tabRuns of tabs from back to front
			for (int i = _runCount - 1; i >= 0; i--) {
				int start = _tabRuns[i];
				int next = _tabRuns[(i == _runCount - 1) ? 0 : i + 1];
				int end = (next != 0 ? next - 1 : tabCount - 1);
				for (int j = start; j <= end; j++) {
					if (_rects[j].intersects(clipRect)) {
						paintTab(g, tabPlacement, _rects, j, iconRect, textRect);
					}
				}
			}

			// Paint selected tab if its in the front run
			// since it may overlap other tabs
			if (selectedIndex >= 0 && getRunForTab(tabCount, selectedIndex) == 0) {
				if (_rects[selectedIndex].intersects(clipRect)) {
					paintTab(g, tabPlacement, _rects, selectedIndex, iconRect,
							textRect);
				}
			}

			if (_tabPane.isOpaque()) {
				g.setColor(_shadow);
				switch (tabPlacement) {
					case LEFT -> {
						if (!isTabLeadingComponentVisible()) {
							g.fillRect(viewRect.x, viewRect.y + 3, 1, 2);
							g.fillRect(viewRect.x + 1, viewRect.y + 2, 1, 1);
							g.fillRect(viewRect.x + 2, viewRect.y + 1, 1, 1);
							g.fillRect(viewRect.x + 3, viewRect.y, 2, 1);
						}
						if (isNoneTabTrailingComponentVisible()) {
							g.fillRect(viewRect.x + 3, viewRect.y + viewRect.height - 1, 2, 1);
							g.fillRect(viewRect.x + 2, viewRect.y + viewRect.height - 2, 1, 1);
							g.fillRect(viewRect.x + 1, viewRect.y + viewRect.height - 3, 1, 1);
							g.fillRect(viewRect.x, viewRect.y + viewRect.height - 5, 1, 2);
						}
						g.setColor(_tabBackground);
						g.fillRect(viewRect.x, viewRect.y, 3, 1);
						g.fillRect(viewRect.x, viewRect.y + 1, 2, 1);
						g.fillRect(viewRect.x, viewRect.y + 2, 1, 1);
					}
					case RIGHT -> {
						if (!isTabLeadingComponentVisible()) {
							g.fillRect(viewRect.x + viewRect.width - 5, viewRect.y, 2, 1);
							g.fillRect(viewRect.x + viewRect.width - 3, viewRect.y + 1, 1, 1);
							g.fillRect(viewRect.x + viewRect.width - 2, viewRect.y + 2, 1, 1);
							g.fillRect(viewRect.x + viewRect.width - 1, viewRect.y + 3, 1, 2);
						}
						if (isNoneTabTrailingComponentVisible()) {
							g.fillRect(viewRect.x + viewRect.width - 5, viewRect.y + viewRect.height - 1, 2, 1);
							g.fillRect(viewRect.x + viewRect.width - 3, viewRect.y + viewRect.height - 2, 1, 1);
							g.fillRect(viewRect.x + viewRect.width - 2, viewRect.y + viewRect.height - 3, 1, 1);
							g.fillRect(viewRect.x + viewRect.width - 1, viewRect.y + viewRect.height - 5, 1, 2);
						}
						g.setColor(_tabBackground);
						g.fillRect(viewRect.x + viewRect.width - 3, viewRect.y, 3, 1);
						g.fillRect(viewRect.x + viewRect.width - 2, viewRect.y + 1, 2, 1);
						g.fillRect(viewRect.x + viewRect.width - 1, viewRect.y + 2, 1, 1);
					}
					case BOTTOM -> {
						if (!isTabLeadingComponentVisible()) {
							g.fillRect(viewRect.x + 3, viewRect.y + viewRect.height - 1, 2, 1);
							g.fillRect(viewRect.x + 2, viewRect.y + viewRect.height - 2, 1, 1);
							g.fillRect(viewRect.x + 1, viewRect.y + viewRect.height - 3, 1, 1);
							g.fillRect(viewRect.x, viewRect.y + viewRect.height - 5, 1, 2);
						}
						if (isNoneTabTrailingComponentVisible()) {
							g.fillRect(viewRect.x + viewRect.width - 5, viewRect.y + viewRect.height - 1, 2, 1);
							g.fillRect(viewRect.x + viewRect.width - 3, viewRect.y + viewRect.height - 2, 1, 1);
							g.fillRect(viewRect.x + viewRect.width - 2, viewRect.y + viewRect.height - 3, 1, 1);
							g.fillRect(viewRect.x + viewRect.width - 1, viewRect.y + viewRect.height - 5, 1, 2);
						}
						g.setColor(_tabBackground);
						g.fillRect(viewRect.x, viewRect.y + viewRect.height - 1, 3, 1);
						g.fillRect(viewRect.x, viewRect.y + viewRect.height - 2, 2, 1);
						g.fillRect(viewRect.x, viewRect.y + viewRect.height - 3, 1, 1);
					}
					default -> {
						if (!isTabLeadingComponentVisible()) {
							g.fillRect(viewRect.x + 3, viewRect.y, 2, 1);
							g.fillRect(viewRect.x + 2, viewRect.y + 1, 1, 1);
							g.fillRect(viewRect.x + 1, viewRect.y + 2, 1, 1);
							g.fillRect(viewRect.x, viewRect.y + 3, 1, 2);
						}
						if (isNoneTabTrailingComponentVisible()) {
							g.fillRect(viewRect.x + viewRect.width - 5, viewRect.y, 2, 1);
							g.fillRect(viewRect.x + viewRect.width - 3, viewRect.y + 1, 1, 1);
							g.fillRect(viewRect.x + viewRect.width - 2, viewRect.y + 2, 1, 1);
							g.fillRect(viewRect.x + viewRect.width - 1, viewRect.y + 3, 1, 2);
						}
						g.setColor(_tabBackground);
						g.fillRect(viewRect.x, viewRect.y, 3, 1);
						g.fillRect(viewRect.x, viewRect.y + 1, 2, 1);
						g.fillRect(viewRect.x, viewRect.y + 2, 1, 1);
					}
				}
			}
		} else {
			super.paintTabArea(g, tabPlacement, selectedIndex, c);
		}
	}

	private boolean isNoneTabTrailingComponentVisible() {
		return !_tabScroller.scrollForwardButton.isVisible() && !_tabScroller.scrollBackwardButton.isVisible() && !_tabScroller.closeButton.isVisible() && !isTabTrailingComponentVisible();
	}


	@Override
	protected void layoutLabel(int tabPlacement, FontMetrics metrics,
	                           int tabIndex, String title, Icon icon, Rectangle tabRect,
	                           Rectangle iconRect, Rectangle textRect, boolean isSelected) {
		textRect.x = textRect.y = iconRect.x = iconRect.y = 0;

		View v = getTextViewForTab(tabIndex);
		if (v != null) {
			_tabPane.putClientProperty("html", v);
		}

		SwingUtilities.layoutCompoundLabel(_tabPane, metrics, title, icon,
				SwingUtilities.CENTER, SwingUtilities.CENTER,
				SwingUtilities.CENTER, SwingUtilities.TRAILING, tabRect,
				iconRect, textRect, _textIconGap);

		_tabPane.putClientProperty("html", null);

		if (tabPlacement == JideTabbedPane.TOP || tabPlacement == JideTabbedPane.BOTTOM) {
			iconRect.x = tabRect.x + _iconMarginHorizon;
			textRect.x = (icon != null ? iconRect.x + iconRect.width + _textIconGap : tabRect.x + _textPadding);
			iconRect.width = Math.min(iconRect.width, tabRect.width - _tabRectPadding);
			textRect.width = tabRect.width - _tabRectPadding - iconRect.width - (icon != null ? _textIconGap : _noIconMargin);

			if ((getTabResizeMode() == JideTabbedPane.RESIZE_MODE_FIT || _tabPane.getTabResizeMode() == JideTabbedPane.RESIZE_MODE_FIXED)) {
				textRect.width -= 10;
				if (isShowCloseButton() && isShowCloseButtonOnTab()) {
					if (_tabPane.isShowCloseButtonOnSelectedTab()) {
						if (isSelected) {
							textRect.width -= _closeButtons[tabIndex].getPreferredSize().width;
						}
					} else {
						textRect.width -= _closeButtons[tabIndex].getPreferredSize().width;
					}
				}
			} else if (getTabResizeMode() == JideTabbedPane.RESIZE_MODE_COMPRESSED && isShowCloseButton() && isShowCloseButtonOnTab()) {
				if (!_tabPane.isShowCloseButtonOnSelectedTab()) {
					if (!isSelected) {
						iconRect.width = iconRect.width
								+ _closeButtons[tabIndex].getPreferredSize().width
								+ _closeButtonMarginSize;
						textRect.width = 0;
					}
				}
			}
		} else {
			iconRect.y = tabRect.y + _iconMarginVertical;
			textRect.y = (icon != null ? iconRect.y + iconRect.height
					+ _textIconGap : tabRect.y + _textPadding);
			iconRect.x = tabRect.x + 3;
			textRect.x = tabRect.x + 3;
			textRect.width = tabRect.width - _textMarginVertical;
			textRect.height = tabRect.height - _tabRectPadding - iconRect.height - (icon != null ? _textIconGap : _noIconMargin);

			if ((getTabResizeMode() == JideTabbedPane.RESIZE_MODE_FIT || _tabPane
					.getTabResizeMode() == JideTabbedPane.RESIZE_MODE_FIXED)) {
				textRect.height -= 10;
				if (isShowCloseButton() && isShowCloseButtonOnTab()) {
					if (_tabPane.isShowCloseButtonOnSelectedTab()) {
						if (isSelected) {
							textRect.height -= _closeButtons[tabIndex].getPreferredSize().height;
						}
					} else {
						textRect.height -= _closeButtons[tabIndex].getPreferredSize().height;
					}
				}
			} else if (getTabResizeMode() == JideTabbedPane.RESIZE_MODE_COMPRESSED
					&& isShowCloseButton() && isShowCloseButtonOnTab()) {
				if (!_tabPane.isShowCloseButtonOnSelectedTab()) {
					if (!isSelected) {
						iconRect.height = iconRect.height + _closeButtons[tabIndex].getPreferredSize().height + _closeButtonMarginSize;
						textRect.height = 0;
					}
				}

			}
		}

	}


	/**
	 * this function draws the border around each tab note that this function does now draw the background of the tab.
	 * that is done elsewhere
	 */
	@Override
	protected void paintTabBorder(Graphics g, int tabPlacement, int tabIndex,
	                              int x, int y, int w, int h, boolean isSelected) {
		if (!PAINT_TAB_BORDER) {
			return;
		}

		if (getTabShape() == JideTabbedPane.SHAPE_ECLIPSE3X) {
			g.setColor(_lightHighlight);
			boolean leftToRight = _tabPane.getComponentOrientation().isLeftToRight();
			switch (tabPlacement) {
				case LEFT -> {
					if (!isTabLeadingComponentVisible())
						y--;
					if (isSelected) {
						g.setColor(_shadow);
						g.drawLine(x + 5, y, x + w - 1, y);// top

						// top left arc
						g.drawLine(x + 4, y + 1, x + 3, y + 1);
						g.drawLine(x + 2, y + 2, x + 2, y + 2);
						g.drawLine(x + 1, y + 3, x + 1, y + 3);
						g.drawLine(x, y + 4, x, y + 5);

						if (isTabTopVisible(tabPlacement)) {
							g.drawLine(x, y + 5, x, y + h - 21);
						}

						// bottom left arc
						g.drawLine(x, y + h - 21, x, y + h - 19);
						g.drawLine(x + 1, y + h - 18, x + 1, y + h - 16);
						g.drawLine(x + 2, y + h - 15, x + 2, y + h - 14);
						g.drawLine(x + 3, y + h - 13, x + 3, y + h - 13);
						g.drawLine(x + 4, y + h - 12, x + 4, y + h - 11);

						// bottom
						for (int i = 0; i < w - 10; i++) {
							g.drawLine(x + 5 + i, y + h - 10 + i, x + 5 + i, y + h - 10 + i);
						}

						// bottom right arc
						g.drawLine(x + w - 5, y + h + w - 20, x + w - 5, y + h + w - 19);
						g.drawLine(x + w - 4, y + h + w - 18, x + w - 4, y + h + w - 18);
						g.drawLine(x + w - 3, y + h + w - 17, x + w - 3, y + h + w - 16);
						g.drawLine(x + w - 2, y + h + w - 15, x + w - 2, y + h + w - 13);
						g.drawLine(x + w - 1, y + h + w - 12, x + w - 1, y + h + w - 10);

						if (!isTabLeadingComponentVisible())
							y++;
						break;
					}

					// not selected
					if (tabIndex > _tabPane.getSelectedIndex()) {
						g.setColor(_shadow);
						g.drawLine(x, y + h - 1, (x + w) - 1, y + h - 1);// bottom

						break;
					}
					if (tabIndex >= _tabPane.getSelectedIndex() || tabIndex == 0)
						break;
					g.setColor(_shadow);
					g.drawLine(x, y - 1, x + w - 1, y - 1);// top
				}
				case RIGHT -> {
					if (!isTabLeadingComponentVisible())
						y--;
					if (isSelected) {
						g.setColor(_shadow);

						g.drawLine(x, y, x + w - 6, y);// top

						// top right arc
						g.drawLine(x + w - 5, y + 1, x + w - 4, y + 1);
						g.drawLine(x + w - 3, y + 2, x + w - 3, y + 2);
						g.drawLine(x + w - 2, y + 3, x + w - 2, y + 3);
						g.drawLine(x + w - 1, y + 4, x + w - 1, y + 5);

						if (isTabTopVisible(tabPlacement)) {
							g.drawLine(x + w - 1, y + 5, x + w - 1, y + h - 21);
						}

						// bottom right arc
						g.drawLine(x + w - 1, y + h - 21, x + w - 1, y + h - 19);
						g.drawLine(x + w - 2, y + h - 18, x + w - 2, y + h - 16);
						g.drawLine(x + w - 3, y + h - 15, x + w - 3, y + h - 14);
						g.drawLine(x + w - 4, y + h - 13, x + w - 4, y + h - 13);
						g.drawLine(x + w - 5, y + h - 12, x + w - 5, y + h - 11);

						// bottom
						for (int i = 0; i < w - 10; i++) {
							g.drawLine(x + w - 6 - i, y + h - 10 + i, x + w - 6 - i, y + h - 10 + i);
						}

						// bottom left arc
						g.drawLine(x + 4, y + h + w - 20, x + 4, y + h + w - 19);
						g.drawLine(x + 3, y + h + w - 18, x + 3, y + h + w - 18);
						g.drawLine(x + 2, y + h + w - 17, x + 2, y + h + w - 16);
						g.drawLine(x + 1, y + h + w - 15, x + 1, y + h + w - 13);
						g.drawLine(x, y + h + w - 12, x, y + h + w - 10);
						break;

					}

					// not selected
					if (tabIndex > _tabPane.getSelectedIndex()) {
						g.setColor(_shadow);
						g.drawLine(x, y + h - 1, (x + w) - 1, y + h - 1);// bottom

						break;
					}
					if (tabIndex >= _tabPane.getSelectedIndex() || tabIndex == 0)
						break;
					g.setColor(_shadow);
					g.drawLine(x, y - 1, x + w - 1, y - 1);// top
				}
				case BOTTOM -> {
					if (!isTabLeadingComponentVisible()) {
						x--;
					}
					if (isSelected) {

						g.setColor(_shadow);

						g.drawLine(x, y + h - 6, x, y);// left

						// left bottom arc
						g.drawLine(x + 1, y + h - 5, x + 1, y + h - 4);
						g.drawLine(x + 2, y + h - 3, x + 2, y + h - 3);
						g.drawLine(x + 3, y + h - 2, x + 3, y + h - 2);
						g.drawLine(x + 4, y + h - 1, x + 5, y + h - 1);

						if (isTabTopVisible(tabPlacement)) {
							g.drawLine(x + 5, y + h - 1, x + w - 20, y + h - 1);
						}

						// right bottom arc
						g.drawLine(x + w - 20, y + h - 1, x + w - 18, y + h - 1);
						g.drawLine(x + w - 17, y + h - 2, x + w - 15, y + h - 2);
						g.drawLine(x + w - 14, y + h - 3, x + w - 13, y + h - 3);
						g.drawLine(x + w - 12, y + h - 4, x + w - 12, y + h - 4);
						g.drawLine(x + w - 11, y + h - 5, x + w - 10, y + h - 5);

						// right
						for (int i = 0; i < h - 10; i++) {
							g.drawLine(x + w - 9 + i, y + h - 6 - i, x + w - 9 + i, y + h - 6 - i);
						}

						// right top arc
						g.drawLine(x + w + h - 19, y + 4, x + w + h - 18, y + 4);
						g.drawLine(x + w + h - 17, y + 3, x + w + h - 17, y + 3);
						g.drawLine(x + w + h - 16, y + 2, x + w + h - 15, y + 2);
						g.drawLine(x + w + h - 14, y + 1, x + w + h - 12, y + 1);
						g.drawLine(x + w + h - 11, y, x + w + h - 9, y);
						break;
					}

					// not selected
					if (tabIndex > _tabPane.getSelectedIndex()) {
						g.setColor(_shadow);
						if (leftToRight) {
							g.drawLine(x + w - 2, y - 1, x + w - 2, y + h);// right
						} else {
							g.drawLine(x, y - 1, x, y + h);// right
						}
						break;
					}
					if (tabIndex >= _tabPane.getSelectedIndex() || tabIndex == 0)
						break;
					g.setColor(_shadow);
					if (leftToRight) {
						g.drawLine(x, y - 1, x, y + h);// left
					} else {
						g.drawLine(x + w - 2, y - 1, x + w - 2, y + h);// left
					}
				}
				default -> {
					if (!isTabLeadingComponentVisible())
						x--;
					if (isSelected) {
						g.setColor(_shadow);

						g.drawLine(x, y + 5, x, y + h);// left

						// left top arc
						g.drawLine(x + 4, y, x + 5, y);
						g.drawLine(x + 3, y + 1, x + 3, y + 1);
						g.drawLine(x + 2, y + 2, x + 2, y + 2);
						g.drawLine(x + 1, y + 3, x + 1, y + 4);

						if (isTabTopVisible(tabPlacement)) {
							g.drawLine(x + 5, y, x + w - 20, y);
						}

						// right top arc
						g.drawLine(x + w - 20, y, x + w - 18, y);
						g.drawLine(x + w - 17, y + 1, x + w - 15, y + 1);
						g.drawLine(x + w - 14, y + 2, x + w - 13, y + 2);
						g.drawLine(x + w - 12, y + 3, x + w - 12, y + 3);
						g.drawLine(x + w - 11, y + 4, x + w - 10, y + 4);

						// right
						for (int i = 0; i < h - 10; i++) {
							g.drawLine(x + w - 9 + i, y + 5 + i, x + w - 9 + i, y + 5 + i);
						}

						// right bottom arc
						g.drawLine(x + w + h - 19, y + h - 5, x + w + h - 18, y + h - 5);
						g.drawLine(x + w + h - 17, y + h - 4, x + w + h - 17, y + h - 4);
						g.drawLine(x + w + h - 16, y + h - 3, x + w + h - 15, y + h - 3);
						g.drawLine(x + w + h - 14, y + h - 2, x + w + h - 12, y + h - 2);
						g.drawLine(x + w + h - 11, y + h - 1, x + w + h - 9, y + h - 1);
						break;
					}
					if (tabIndex > _tabPane.getSelectedIndex()) {
						g.setColor(_shadow);
						if (leftToRight) {
							g.drawLine(x + w - 2, y, x + w - 2, y + (h - 1));// right
						} else {
							g.drawLine(x, y, x, y + (h - 1));// left
						}
						break;
					}
					if (tabIndex >= _tabPane.getSelectedIndex() || tabIndex == 0)
						break;
					g.setColor(_shadow);
					if (leftToRight) {
						g.drawLine(x, y, x, y + (h - 1));// left
					} else {
						g.drawLine(x + w - 2, y, x + w - 2, y + (h - 1));// left
					}
				}
			}
		} else {
			super.paintTabBorder(g, tabPlacement, tabIndex, x, y, w, h, isSelected);
		}
	}

	@Override
	protected void paintTabBackground(Graphics g, int tabPlacement,
	                                  int tabIndex, int x, int y, int w, int h, boolean isSelected) {
		if (!PAINT_TAB_BACKGROUND) {
			return;
		}

		if (!isSelected) {
			return;
		}

		if (getTabShape() == JideTabbedPane.SHAPE_ECLIPSE3X) {
			Graphics2D g2d = (Graphics2D) g;
			Color background1;
			Color background2;
			if (showFocusIndicator()) {
				background1 = _activeBackground;
				background2 = UIDefaultsLookup.getColor("DockableFrame.activeTitleBackground2");
			} else {
				background1 = _activeBackground;
				background2 = _background;
			}

			switch (tabPlacement) {
				case LEFT -> {
					if (!isTabLeadingComponentVisible())
						y--;
					int[] xp = {x + w, x + 5, x, x, x + 6, x + w - 6, x + w};
					int[] yp = {y, y, y + 4, y + h - 19, y + h - 8,
							y + h + w - 21, y + h + w - 10};
					int np = yp.length;
					Polygon p = new Polygon(xp, yp, np);
					UIUtil.fillGradient(g2d, p, background1, background2, false);
				}
				case RIGHT -> {
					if (!isTabLeadingComponentVisible())
						y--;
					int[] xp = {x, x + w - 6, x + w, x + w, x + w - 5, x + 5, x};
					int[] yp = {y, y, y + 4, y + h - 21, y + h - 10,
							y + h + w - 21, y + h + w - 10};
					int np = yp.length;
					Polygon p = new Polygon(xp, yp, np);
					UIUtil.fillGradient(g2d, p, background2, background1, false);
				}
				case BOTTOM -> {
					if (!isTabLeadingComponentVisible())
						x--;
					// not box style
					int[] xp = {x, x, x + 6, x + w - 20, x + w - 16, x + w - 14,
							x + w - 12, x + w - 9, x + w + h - 19, x + w + h - 10,
							x + w + h - 12};
					int[] yp = {y, y + h - 6, y + h, y + h, y + h - 2, y + h - 3,
							y + h - 4, y + h - 6, y + 4, y + 1, y};
					int np = yp.length;
					Polygon p = new Polygon(xp, yp, np);
					UIUtil.fillGradient(g2d, p, background2, background1, true);
				}
				default -> {
					if (!isTabLeadingComponentVisible())
						x--;
					int[] xp = {x, x, x + 2, x + 3, x + 6, x + w - 20, x + w - 14,
							x + w - 12, x + w - 9, x + w + h - 20, x + w + h - 9};
					int[] yp = {y + h, y + 5, y + 2, y + 1, y, y, y + 2, y + 3,
							y + 5, y + h - 6, y + h};
					int np = xp.length;
					Polygon p = new Polygon(xp, yp, np);
					UIUtil.fillGradient(g2d, p, background1, background2, true);
				}
			}
		} else {
			super.paintTabBackground(g, tabPlacement, tabIndex, x, y, w, h, isSelected);
		}
	}


	@Override
	protected void paintContentBorder(Graphics g, int tabPlacement, int selectedIndex) {
		if (selectedIndex < 0) {
			return;
		}

		if (getTabShape() == JideTabbedPane.SHAPE_ECLIPSE3X) {
			int width = _tabPane.getWidth();
			int height = _tabPane.getHeight();
			Insets insets = _tabPane.getInsets();

			int x = insets.left;
			int y = insets.top;
			int w = width - insets.right - insets.left;
			int h = height - insets.top - insets.bottom;

			int temp = -1;
			switch (tabPlacement) {
				case LEFT -> {
					x += calculateTabAreaWidth(tabPlacement, _runCount, _maxTabWidth);
					if (isTabLeadingComponentVisible()) {
						if (_tabLeadingComponent.getSize().width > calculateTabAreaWidth(tabPlacement, _runCount, _maxTabWidth)) {
							x = insets.left + _tabLeadingComponent.getSize().width;
							temp = _tabLeadingComponent.getSize().width;
						}
					}
					if (isTabTrailingComponentVisible()) {
						if (_maxTabWidth < _tabTrailingComponent.getSize().width
								&& temp < _tabTrailingComponent.getSize().width) {
							x = insets.left + _tabTrailingComponent.getSize().width;
						}
					}
					w -= (x - insets.left);
				}
				case RIGHT -> w -= calculateTabAreaWidth(tabPlacement, _runCount, _maxTabWidth);
				case BOTTOM -> h -= calculateTabAreaHeight(tabPlacement, _runCount, _maxTabHeight);
				default -> {
					y += calculateTabAreaHeight(tabPlacement, _runCount, _maxTabHeight);
					if (isTabLeadingComponentVisible()) {
						if (_tabLeadingComponent.getSize().height > calculateTabAreaHeight(tabPlacement, _runCount, _maxTabHeight)) {
							y = insets.top + _tabLeadingComponent.getSize().height;
							temp = _tabLeadingComponent.getSize().height;
						}
					}
					if (isTabTrailingComponentVisible()) {
						if (_maxTabHeight < _tabTrailingComponent.getSize().height
								&& temp < _tabTrailingComponent.getSize().height) {
							y = insets.top + _tabTrailingComponent.getSize().height;
						}
					}
					h -= (y - insets.top);
				}
			}

			// Fill region behind content area
			paintContentBorder(g, x, y, w, h);

			Rectangle viewRect = _tabScroller.viewport.getViewRect();
			Rectangle r = _rects[selectedIndex];
			Rectangle button = _tabScroller.scrollForwardButton.getBounds();
			Rectangle panel = _tabScroller.tabPanel.getBounds();
			int lsize = 0;

			if (_tabPane.getTabPlacement() == TOP || _tabPane.getTabPlacement() == BOTTOM) {
				if (isTabLeadingComponentVisible()) {
					lsize = _tabLeadingComponent.getSize().width;
				}
			} else {
				if (isTabLeadingComponentVisible()) {
					lsize = _tabLeadingComponent.getSize().height;
				}
			}


			switch (tabPlacement) {
				case LEFT -> {
					if (r.y < viewRect.y + viewRect.height
							&& r.y + r.height
							+ _tabPane.getBoundsAt(selectedIndex).width - 9 > viewRect.y
							+ viewRect.height) {

						if (selectedIndex != _tabPane.getTabCount() - 1) {
							viewRect.y += (r.y + r.height + _tabPane.getBoundsAt(selectedIndex).width - 9 - (viewRect.y + viewRect.height));
							_tabScroller.viewport.setViewPosition(new Point(
									viewRect.x, viewRect.y));
						} else {
							if (panel.y + panel.height + lsize > button.y) {
								viewRect.y += (r.y + r.height + _tabPane.getBoundsAt(selectedIndex).width - 9 - (viewRect.y + viewRect.height));
								_tabScroller.viewport.setViewPosition(new Point(
										viewRect.x, viewRect.y));
							} else {
								_tabScroller.viewport.setSize(viewRect.width, viewRect.height + getLayoutSize());
							}

						}

					}
					paintContentBorderLeftEdge(g, tabPlacement, selectedIndex, x, y, w, h);
				}
				case RIGHT -> {
					if (r.y < viewRect.y + viewRect.height
							&& r.y + r.height
							+ _tabPane.getBoundsAt(selectedIndex).width - 9 > viewRect.y
							+ viewRect.height) {

						if (selectedIndex != _tabPane.getTabCount() - 1) {
							viewRect.y += (r.y + r.height + _tabPane.getBoundsAt(selectedIndex).width - 9 - (viewRect.y + viewRect.height));
							_tabScroller.viewport.setViewPosition(new Point(viewRect.x, viewRect.y));
						} else {
							if (panel.y + panel.height + lsize > button.y) {
								viewRect.y += (r.y + r.height + _tabPane.getBoundsAt(selectedIndex).width - 9 - (viewRect.y + viewRect.height));
								_tabScroller.viewport.setViewPosition(new Point(viewRect.x, viewRect.y));
							} else {
								_tabScroller.viewport.setSize(viewRect.width, viewRect.height + getLayoutSize());
							}

						}

					}
					paintContentBorderRightEdge(g, tabPlacement, selectedIndex, x, y, w, h);
				}
				case BOTTOM -> {
					if (r.x < viewRect.x + viewRect.width
							&& r.x + r.width
							+ _tabPane.getBoundsAt(selectedIndex).height
							- 9 > viewRect.x + viewRect.width) {
						if (selectedIndex != _tabPane.getTabCount() - 1) {
							viewRect.x += (r.x + r.width + _tabPane.getBoundsAt(selectedIndex).height - 9 - (viewRect.x + viewRect.width));
							_tabScroller.viewport.setViewPosition(new Point(
									viewRect.x, viewRect.y));
						} else {
							if (panel.x + panel.width + lsize > button.x) {
								viewRect.x += (r.x + r.width + _tabPane.getBoundsAt(selectedIndex).height - 9 - (viewRect.x + viewRect.width));
								_tabScroller.viewport.setViewPosition(new Point(viewRect.x, viewRect.y));
							} else {
								_tabScroller.viewport.setSize(viewRect.width + getLayoutSize(), viewRect.height);
							}

						}

					}
					paintContentBorderBottomEdge(g, tabPlacement, selectedIndex, x, y, w, h);
				}
				default -> {
					if (r.x < viewRect.x + viewRect.width && r.x + r.width + _tabPane.getBoundsAt(selectedIndex).height - 9 > viewRect.x + viewRect.width) {
						if (selectedIndex != _tabPane.getTabCount() - 1) {
							viewRect.x += (r.x + r.width + _tabPane.getBoundsAt(selectedIndex).height - 9 - (viewRect.x + viewRect.width));
							_tabScroller.viewport.setViewPosition(new Point(viewRect.x, viewRect.y));
						} else {
							if (panel.x + panel.width + lsize > button.x) {
								viewRect.x += (r.x + r.width + _tabPane.getBoundsAt(selectedIndex).height - 9 - (viewRect.x + viewRect.width));
								_tabScroller.viewport.setViewPosition(new Point(viewRect.x, viewRect.y));

							} else {
								_tabScroller.viewport.setSize(viewRect.width + getLayoutSize(), viewRect.height);
							}
						}
					}
					paintContentBorderTopEdge(g, tabPlacement, selectedIndex, x, y, w, h);
				}
			}

			g.setColor(_shadow);
			if (_tabPane.isTabShown()) {
				switch (tabPlacement) {
					case LEFT -> {
						g.drawLine(width - 1, 0, width - 1, height - 1);
						g.drawLine(6, 0, width - 1, 0);
						g.drawLine(6, height - 1, width - 1, height - 1);
						g.drawLine(0, 6, 0, height - 7);
						g.drawLine(1, height - 6, 1, height - 5);
						g.drawLine(2, height - 4, 2, height - 4);
						g.drawLine(3, height - 3, 3, height - 3);
						g.drawLine(4, height - 2, 5, height - 2);
						g.drawLine(4, 1, 5, 1);
						g.drawLine(3, 2, 3, 2);
						g.drawLine(2, 3, 2, 3);
						g.drawLine(1, 4, 1, 5);
					}
					case RIGHT -> {
						g.drawLine(0, 0, 0, height - 1);
						g.drawLine(0, 0, width - 7, 0);
						g.drawLine(0, height - 1, width - 7, height - 1);
						g.drawLine(width - 1, 6, width - 1, height - 7);
						g.drawLine(width - 2, height - 6, width - 2, height - 5);
						g.drawLine(width - 3, height - 4, width - 3, height - 4);
						g.drawLine(width - 4, height - 3, width - 4, height - 3);
						g.drawLine(width - 5, height - 2, width - 6, height - 2);
						g.drawLine(width - 6, 1, width - 5, 1);
						g.drawLine(width - 4, 2, width - 4, 2);
						g.drawLine(width - 3, 3, width - 3, 3);
						g.drawLine(width - 2, 4, width - 2, 5);
					}
					case BOTTOM -> {
						g.drawLine(0, 0, width - 1, 0);
						g.drawLine(0, 0, 0, height - 7);
						g.drawLine(width - 1, 0, width - 1, height - 7);
						g.drawLine(6, height - 1, width - 7, height - 1);
						g.drawLine(width - 6, height - 2, width - 5, height - 2);
						g.drawLine(width - 4, height - 3, width - 4, height - 3);
						g.drawLine(width - 3, height - 4, width - 3, height - 4);
						g.drawLine(width - 2, height - 5, width - 2, height - 6);
						g.drawLine(1, height - 6, 1, height - 5);
						g.drawLine(2, height - 4, 2, height - 4);
						g.drawLine(3, height - 3, 3, height - 3);
						g.drawLine(4, height - 2, 5, height - 2);
					}
					default -> {
						g.drawLine(6, 0, width - 7, 0);
						g.drawLine(0, height - 1, width - 1, height - 1);
						g.drawLine(width - 1, 6, width - 1, height - 1);
						g.drawLine(0, 6, 0, height - 1);
						g.drawLine(width - 6, 1, width - 5, 1);
						g.drawLine(width - 4, 2, width - 4, 2);
						g.drawLine(width - 3, 3, width - 3, 3);
						g.drawLine(width - 2, 4, width - 2, 5);
						g.drawLine(4, 1, 5, 1);
						g.drawLine(3, 2, 3, 2);
						g.drawLine(2, 3, 2, 3);
						g.drawLine(1, 4, 1, 5);
					}
				}
			} else {
				g.drawRect(0, 0, width - 1, height - 1);
			}
		} else {
			super.paintContentBorder(g, tabPlacement, selectedIndex);
		}

	}

	// paint the component border of every tab

	@Override
	protected void paintContentBorder(Graphics g, int x, int y, int w, int h) {
		if (!PAINT_CONTENT_BORDER) {
			return;
		}

		if (getTabShape() == JideTabbedPane.SHAPE_ECLIPSE3X) {
			if (showFocusIndicator()) {
				Insets insets = getContentBorderInsets(_tabPane.getTabPlacement());
				Color selectedTitleColor2 = UIDefaultsLookup.getColor("DockableFrame.activeTitleBackground2");
				g.setColor(selectedTitleColor2);
				g.fillRect(x, y, w, insets.top); // top
				g.fillRect(x, y, insets.left, h); // left
				g.fillRect(x, y + h - insets.bottom, w, insets.bottom); // bottom
				g.fillRect(x + w - insets.right, y, insets.right, h); // right
			}
		} else {
			super.paintContentBorder(g, x, y, w, h);
		}
	}

	// paint the top line of the content when the tab is on the top

	@Override
	protected void paintContentBorderTopEdge(Graphics g, int tabPlacement,
	                                         int selectedIndex, int x, int y, int w, int h) {
		if (!PAINT_CONTENT_BORDER_EDGE) {
			return;
		}

		if (selectedIndex < 0) {
			return;
		}

		if (getTabShape() == JideTabbedPane.SHAPE_ECLIPSE3X) {
			Rectangle selRect = getTabBounds(selectedIndex, _calcRect);

			Rectangle viewRect = _tabScroller.viewport.getViewRect();
			Rectangle r = _rects[selectedIndex];

			g.setColor(getPainter().getControlShadow());

			// Break line to show visual connection to selected tab
			if (isTabLeadingComponentVisible() && selRect.x > 0) {
				g.drawLine(x, y, selRect.x, y);
			}

			if (r.x > viewRect.x) {
				g.drawLine(x, y, selRect.x - 1, y);
			}

			if (_tabPane.isTabShown()) {
				if (r.x >= viewRect.x + viewRect.width) {
					g.drawLine(x, y, x + w - 1, y);
				} else {
					g.drawLine(selRect.x + selRect.width + _tabPane.getBoundsAt(selectedIndex).height - 9, y, x + w - 1, y);
				}
			}
		} else {
			super.paintContentBorderTopEdge(g, tabPlacement, selectedIndex, x, y, w, h);
		}
	}

	// paint the bottom line of the content when the tab is on the bottom

	@Override
	protected void paintContentBorderBottomEdge(Graphics g, int tabPlacement,
	                                            int selectedIndex, int x, int y, int w, int h) {
		if (!PAINT_CONTENT_BORDER_EDGE) {
			return;
		}

		if (selectedIndex < 0) {
			return;
		}

		if (getTabShape() == JideTabbedPane.SHAPE_ECLIPSE3X) {
			Rectangle selRect = getTabBounds(selectedIndex, _calcRect);

			g.setColor(getPainter().getControlShadow());

			Rectangle viewRect = _tabScroller.viewport.getViewRect();
			Rectangle r = _rects[selectedIndex];

			if (isTabLeadingComponentVisible() && selRect.x > 0) {
				g.drawLine(x, y + h - 1, selRect.x, y + h - 1);
			}

			// Break line to show visual connection to selected tab
			if (r.x > viewRect.x) {
				g.drawLine(x, y + h - 1, selRect.x - 1, y + h - 1);
			}

			if (_tabPane.isTabShown()) {
				if (r.x >= viewRect.x + viewRect.width) {
					g.drawLine(x, y + h - 1, x + w - 1, y + h - 1);
				} else {
					g.drawLine(selRect.x + selRect.width + _tabPane.getBoundsAt(selectedIndex).height - 9, y + h - 1, x + w - 1, y + h - 1);
				}
			}
		} else {
			super.paintContentBorderBottomEdge(g, tabPlacement, selectedIndex, x, y, w, h);
		}

	}

//  paint the left line of the content when the tab is on the left

	@Override
	protected void paintContentBorderLeftEdge(Graphics g, int tabPlacement,
	                                          int selectedIndex, int x, int y, int w, int h) {
		if (!PAINT_CONTENT_BORDER_EDGE) {
			return;
		}

		if (selectedIndex < 0) {
			return;
		}

		if (getTabShape() == JideTabbedPane.SHAPE_ECLIPSE3X) {
			Rectangle selRect = getTabBounds(selectedIndex, _calcRect);

			Rectangle viewRect = _tabScroller.viewport.getViewRect();
			Rectangle r = _rects[selectedIndex];

			g.setColor(getPainter().getControlShadow());

			if (isTabLeadingComponentVisible() && selRect.y > 0) {
				g.drawLine(x, y, x, selRect.y);
			}

			// Break line to show visual connection to selected tab
			if (r.y - 2 > viewRect.y) {
				g.drawLine(x, y, x, selRect.y - 3);
			}

			if (_tabPane.isTabShown()) {
				if (r.y >= viewRect.y + viewRect.height) {
					g.drawLine(x, y, x, y + h - 1);
				} else {
					g.drawLine(x, selRect.y + selRect.height + _tabPane.getBoundsAt(selectedIndex).width - 9, x, y + h - 1);
				}
			}
		} else {
			super.paintContentBorderLeftEdge(g, tabPlacement, selectedIndex, x, y, w, h);
		}
	}

//  paint the right line of the content when the tab is on the right

	@Override
	protected void paintContentBorderRightEdge(Graphics g, int tabPlacement,
	                                           int selectedIndex, int x, int y, int w, int h) {
		if (!PAINT_CONTENT_BORDER_EDGE) {
			return;
		}

		if (selectedIndex < 0) {
			return;
		}

		if (getTabShape() == JideTabbedPane.SHAPE_ECLIPSE3X) {
			Rectangle selRect = getTabBounds(selectedIndex, _calcRect);

			Rectangle viewRect = _tabScroller.viewport.getViewRect();
			Rectangle r = _rects[selectedIndex];

			g.setColor(getPainter().getControlShadow());

			if (isTabLeadingComponentVisible() && selRect.y > 0) {
				g.drawLine(x + w - 1, y, x + w - 1, selRect.y);
			}

			// Break line to show visual connection to selected tab
			if (r.y - 2 > viewRect.y) {
				g.drawLine(x + w - 1, y, x + w - 1, selRect.y - 3);
			}

			if (_tabPane.isTabShown()) {
				if (r.y >= viewRect.y + viewRect.height) {
					g.drawLine(x + w - 1, y, x + w - 1, y + h - 1);
				} else {
					g.drawLine(x + w - 1, selRect.y + selRect.height + _tabPane.getBoundsAt(selectedIndex).width - 9, x + w - 1, y + h - 1);
				}
			}
		} else {
			super.paintContentBorderRightEdge(g, tabPlacement, selectedIndex, x, y, w, h);
		}
	}


	@Override
	protected Rectangle getTabsTextBoundsAt(int tabIndex) {
		Rectangle tabRect = _tabPane.getBoundsAt(tabIndex);
		Rectangle iconRect = new Rectangle(), textRect = new Rectangle();

		String title = _tabPane.getDisplayTitleAt(tabIndex);
		Icon icon = _tabPane.getIconForTab(tabIndex);

		SwingUtilities.layoutCompoundLabel(_tabPane, _tabPane.getGraphics()
						.getFontMetrics(_tabPane.getFont()), title, icon,
				SwingUtilities.CENTER, SwingUtilities.CENTER,
				SwingUtilities.CENTER, SwingUtilities.TRAILING, tabRect,
				iconRect, textRect, icon == null ? 0 : _textIconGap);

		if (_tabPane.getTabPlacement() == JideTabbedPane.TOP || _tabPane.getTabPlacement() == JideTabbedPane.BOTTOM) {
			iconRect.x = tabRect.x + _iconMarginHorizon;
			textRect.x = (icon != null ? iconRect.x + iconRect.width + _textIconGap : tabRect.x + _textPadding);
		} else {
			iconRect.y = tabRect.y + _iconMarginVertical;
			textRect.y = (icon != null ? iconRect.y + iconRect.height + _textIconGap : tabRect.y + _textPadding);
			iconRect.x = tabRect.x + 2;
			textRect.x = tabRect.x + 2;
		}

		return textRect;
	}


	@Override
	protected void paintFocusIndicator(Graphics g, int tabPlacement,
	                                   Rectangle[] rects, int tabIndex, Rectangle iconRect,
	                                   Rectangle textRect, boolean isSelected) {
		Rectangle tabRect = rects[tabIndex];
		if (_tabPane.hasFocus() && isSelected) {
			int x, y, w, h;
			g.setColor(_focus);
			switch (tabPlacement) {
				case LEFT, RIGHT -> {
					x = tabRect.x + 2;
					y = tabRect.y + 3;
					w = tabRect.width - 4;
					h = tabRect.height - 19;
				}
				default -> {
					x = tabRect.x + 3;
					y = tabRect.y + 2;
					w = tabRect.width - 19;
					h = tabRect.height - 3;
				}
			}
			BasicGraphicsUtils.drawDashedRect(g, x, y, w, h);
		}
	}

}
